package server;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

public class RefrensMonitor {

	private static RefrensMonitor refrensMonitor;
	private PrintWriter log;
	private int idcount;
	private List<Record> records;

	private RefrensMonitor() {
		records = new LinkedList<Record>();
		records.add(new Record("Bob", "Doc1", "Nurse1", "Division1", idcount++));
		records.add(new Record("Bob", "Doc2", "Nurse2", "Division2", idcount++));
		records.add(new Record("Alice", "Doc1", "Nurse1", "Division1",
				idcount++));
		records.add(new Record("Alice", "Doc1", "Nurse1", "Division2",
				idcount++));
		records.get(0).append("Hello bob");
		records.get(1).append("Good to see you again, Bob");
		records.get(2).append("Hello Alice");
		records.get(3).append("Good to see you again, Alice ");
		try {
			log = new PrintWriter("log.log");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	public static RefrensMonitor getInstance() {
		if (refrensMonitor == null) {
			refrensMonitor = new RefrensMonitor();
		}
		return refrensMonitor;
	}

	public String read(Subject sub, int entry) throws AccessDeniedException {
		switch (sub.getPostion()) {
		case DOC:
			for (Record rec : records) {
				if (rec.getId() == entry) {
					if (rec.getDoc().equals(sub.getName())
							|| rec.getDivision().equals(sub.getDevision())) {
						log.println( new Date() + " :access granted to read record number "
								+ entry + " for: " + sub.getName());
						log.flush();
						return rec.getMessage();
					}
				}
			}

			break;
		case NURSE:
			for (Record rec : records) {
				if (rec.getId() == entry) {
					if (rec.getNurse().equals(sub.getName())
							|| rec.getDivision().equals(sub.getDevision())) {
						log.println(new Date() + " :access granted to read record number "
								+ entry + " for: " + sub.getName());
						log.flush();
						return rec.getMessage();
					}
				}
			}
			break;
		case GA:
			for (Record rec : records) {
				if (rec.getId() == entry) {
					log.println(new Date() + " :access granted to read record number " + entry
							+ " for: " + sub.getName());
					log.flush();
					return rec.getMessage();
				}
			}
			break;
		case PATIENT:
			for (Record rec : records) {
				if (rec.getId() == entry) {
					if (rec.getName().equals(sub.getName())) {
						log.println(new Date() + " :access granted to read record number "
								+ entry + " for: " + sub.getName());
						log.flush();
						return rec.getMessage();
					}
				}
			}

			break;

		}
		log.println(new Date() +" :access denied to read number " + entry + " for: "
				+ sub.getName());
		log.flush();
		throw new AccessDeniedException();
	}
	
	public int add(Subject sub, String name, String nurse , String devision) throws AccessDeniedException{
		if(sub.getPostion() == Position.DOC){
			records.add(new Record(name, sub.getName(), nurse, devision, idcount++));
			log.println(new Date() +" :access granted to add record for: "
					+ sub.getName() + " record nr:" + (idcount - 1) + " was created");
			log.flush();
			return idcount-1;
		}
		log.println(new Date() + " :access denied to add record for: "
				+ sub.getName());
		log.flush();
		throw new AccessDeniedException();
	}
	
	public void remove(Subject sub, int entry ) throws AccessDeniedException{
		if(sub.getPostion() == Position.GA){
			for(int i = 0; i < records.size(); i++){
				if(records.get(i).getId() == entry){
					records.remove(entry);
					log.println(new Date() +" :access granted to remove record nr: " + i +" for: "
							+ sub.getName());
					log.flush();
					return;
				}
			}
			
		}
		log.println(new Date() + " :access denied to remove record for: "
				+ sub.getName());
		log.flush();
		throw new AccessDeniedException();
	}
	
	public void write(Subject sub, int entry , String message) throws AccessDeniedException {
		switch (sub.getPostion()) {
		case DOC:
			for (Record rec : records) {
				if (rec.getId() == entry) {
					if (rec.getDoc().equals(sub.getName())) {
						rec.append(message);
						log.println(new Date() +" :access granted to write record number "
								+ entry + " for: " + sub.getName());
						log.flush();
						return;
					}
				}
			}

			break;
		case NURSE:
			for (Record rec : records) {
				if (rec.getId() == entry) {
					if (rec.getNurse().equals(sub.getName())) {
						rec.append(message);
						log.println(new Date() +" :access granted to write record number "
								+ entry + " for: " + sub.getName());
						log.flush();
						return;
					}
				}
			}
			break;
		default:
			break;
		}
		log.println( new Date() + " :access denied to write to number " + entry + " for: "
				+ sub.getName());
		log.flush();
		throw new AccessDeniedException();
	}
	

}
